package com.whsxt.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.whsxt.constant.AuthConstant;
import com.whsxt.domain.SysUser;
import com.whsxt.domain.User;
import com.whsxt.mapper.MyUserDetailMapper;
import com.whsxt.mapper.SysUserMapper;
import com.whsxt.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.List;

/**
 * @Author: caoqingwen
 * @CreateTime: 2021-03-11 11:19
 * @Description:
 */
@Service
public class UserDetailsServiceImpl implements UserDetailsService {


    @Autowired
    private SysUserMapper sysUserMapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private MyUserDetailMapper myUserDetailMapper;

    @Value("${wx.appid}")
    private String appId;

    @Value("${wx.appsecret}")
    private String appSecret;

    @Value("${wx.url}")
    private String wxUrl;

    @Autowired
    private RestTemplate restTemplate;


    /**
     * 登录方法
     * 前台用户和后台用户公用一套登录
     * 在header里放一个标识区分是前台还是后台
     *
     * @param username
     * @return
     * @throws UsernameNotFoundException
     */
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        //获取request
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = requestAttributes.getRequest();
        //获取头信息
        String loginType = request.getHeader(AuthConstant.LOGIN_TYPE);
        if (StringUtils.isEmpty(loginType)) {
            return null;
        }

        //选择
        switch (loginType) {
            case AuthConstant.SYS_USER:
                //后台用户，查后台用户表sys_user,状态userDetails会判断
                SysUser sysUser = sysUserMapper.selectOne(new LambdaQueryWrapper<SysUser>()
                        .eq(SysUser::getUsername, username)
                );

                if (!ObjectUtils.isEmpty(sysUser)) {
                    //查询权限
                    List<String> auths = sysUserMapper.findUserAuthsById(sysUser.getUserId());
                    if (!CollectionUtils.isEmpty(auths)) {
                        //设置权限
                        sysUser.setAuths(auths);
                    }
                }
                return sysUser;

            case AuthConstant.MEMBER:
                //前台用户，查前台用户表user
                //拿到code就是username，前台传过来的
                //组装url。发请求到微信
                String url = String.format(wxUrl, appId, appSecret, username);
                String wxStr = restTemplate.getForObject(url, String.class);
                //转成json
                JSONObject wxJson = JSON.parseObject(wxStr);
                //拿到openId,作为用户的唯一标识
                String openid = wxJson.getString("openid");
                if (!StringUtils.isEmpty(openid)) {
                    //查询数据库，有：说明之前登陆过，没有就要注册
                    User user = userMapper.selectById(openid);
                    if (user == null) {
                        //注册
                        user = addUser(openid);
                    }
                    return user;
                }
                return null;
            default:
                return null;

        }
    }


    /**
     * 注册用户的方法  因为微信小程序不需要注册，所以当用户第一次登陆我们就需要给用户注册
     *
     * @param openid
     * @return
     */
    private User addUser(String openid) {
        ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = servletRequestAttributes.getRequest();
        String ip = request.getRemoteAddr();

        User user = new User();
        user.setUserId(openid);
        user.setStatus(1);
        user.setModifyTime(new Date());
        user.setUserRegtime(new Date());
        user.setUserLasttime(new Date());
        user.setUserLastip(ip);
        userMapper.insert(user);
        return user;
    }
}
